אלגוריתמים קומבינטוריים סיכומים של תרגילי כיתה מסמסטרים קודמים בנושא מיון ובעיית הבחירה 1. סיכום אלגוריתמי המיון שנלמד: הנחות והערות זכרון נוסף זמן (טוב) זמן (ממוצע) זמן (גרוע) האלגוריתם מיון במקום O(1) O(n) O(n 2 ) INSERTION-SORT O(n) O(n log n) O(n log n) O(n log n) MERGE-SORT מהר בפעל O(1) O(n log n) O(n log n) O(n 2 ) QUICK-SORT מיון במקום O(1) O(n log n) O(n log n) O(n log n) HEAP-SORT a i {1, 2,..., k} O(n + k) O(n + k) O(n + k) O(n + k) COUNTING-SORT d ספרות, k סימנים O(n + k) O(d(n + k)) O(d(n + k)) O(d(n + k)) RADIX-SORT מפולג אחיד O(n) O(n) O(n) O(n log n) BUCKET-SORT :INSERTION-SORT.2 קלט: סדרה.a 1, a 2,..., a n פלט: הסדרה ממוינת בסדר לא יורד: a 1, a 2,..., a n כך ש.a 1 a 2... a n (א) האלגוריתם: נניח שהסדרה כבר מופיע במערך [n 1]A.... INSERTION-SORT(A) 1 for j 2 to length[a] 2 do key A[j] 3 Insert A[j] into the sorted sequence A[1... (j 1)] 4 i j 1 5 while i > 0 and A[i] > key 6 do A[i + 1] A[i] 7 i i 1 8 A[i + 1] key (ב) דוגמה: 3] [6, 2, 4, = A או משהוא דומה. (ג) ניתוח סיבוכיות ל.INSERTION-SORT (מספר השוואות. מספר הזזות. אפשרות לשיפור מספר ההשוואות.).MERGE-SORT.3 (א) האלגוריתם: נניח שהסדרה כבר מופיע במערך [n 1]A.... MERGE-SORT(A, p, r) 1 if p < r 2 then q (p + r)/2 3 MERGE-SORT(A, p, q) 4 MERGE-SORT(A, q + 1, r) 5 MERGE(A, p, q, r) (ב) דוגמה: 3] [6, 2, 4, =.A (ג) ניתוח הסיבוכיות ל MERGE-SORT מבוסס על נוסחת הנסיגה: { n + 2T (n/2), n 2 T (n) = 1, n < 2 1 שעבורו מתקיים n).t (n) = Θ(n log
.QUICK-SORT.4 (א) האלגוריתם: נניח שהסדרה כבר מופיע במערך [n 1]A.... QUICK-SORT(A, p, r) 1 if p < r 2 then q PARTITION(A, p, r) 3 QUICK-SORT(A, p, q) 4 QUICK-SORT(A, q + 1, r) PARTITION(A, p, r) 1 x A[p] 2 i p 1 3 j r + 1 4 while true 5 do repeat j j 1 6 until A[j] x 7 repeat i i + 1 8 until A[i] x 9 if i < j 10 then exchange A[i] A[j] 11 else return j (ב) דוגמה: 3] [6, 2, 4, =.A (ג) ניתוח הסיבוכיות ל QUICK-SORT מבוסס על שיטות הסתברותיות. (ד) האלגוריתם הוא מהר מאוד בפעל (קבוע נמוך למקרה הממוצע). :COUNTING-SORT.5 (א) אלגוריתם זה עובד תחת ההנחה כי המספרים הם מספרים טבעיים חסומים על ידי,k כלומר מהקבוצה k},... 2,.{1, (ב) האלגוריתם: נניח שהסדרה כבר מופיע במערך [n 1]A.... COUNTING-SORT(A, B, k) 1 for i 1 to k 2 do C[i] 0 3 for j 1 to length[a] 4 do C[A[j]] C[A[j]] + 1 5 C[i] is the number of times i appears as an entry in A. 6 for i 2 to k 7 do C[i] C[i] + C[i 1] 8 C[i] is the now the number of elements i appearing in A. 9 for j length[a] downto 1 10 do B[C[A[j]]] A[j] 11 C[A[j]] C[A[j]] 1 (ג) האלגוריתם יציב בצורה הנ ל. מתוך הנחה שאין מידע נלווה. תיארנו בתרגיל גישה פשוטה יותר שאינה יציבה (ד) דוגמה כאשר = 6 :k.a = [6, 5, 2, 4, 3, 6, 4, 1, 3, 2, 5, 4] 2
:BUCKET-SORT.6 (א) אלגוריתם זה עובד תחת ההנחה כי ממיינים מספרים המפולגים באופן אחיד בתחום מסוים (אך חזרות מותרות). (ב) האלגוריתם: נניח שהסדרה כבר מופיע במערך [n 1]A.... BUCKET-SORT(A) We divide the allowed range into n equally sized consecutive buckets. 1 for i 1 to length[a] 2 do Place A[i] into the appropriate bucket. 3 Sort each one of the n buckets (using heap or merge sort). 4 Output the (sorted) contents of each bucket according to the order of the buckets. (ג) דוגמה של מספרים טבעיים מפולגים בקבוצה 99}, 98,... 2, :{0, 1,.A = [78, 21, 49, 67, 89, 29, 12, 46, 81, 17] (ד) ניתוח סיבוכיות (בשיטה הסתברותית) כאשר המיון הפנימי נעשה לפי MERGE-.HEAP-SORT או SORT 7. מיון יציב: הגדרה: אלגוריתם מיון נקרא יתיב אם שני אברים שווי ערך (בהשוואה) רשומים בסדר המקורי בפלט. הגדרה זו משמעותית רק כאשר יש מידע נלווה. דוגמה: נניח שממינים אנשים לפי היום הולדת שלהם. (נניח לשם פשטות שרק מטפלים באנשים שנולדו בחודש ינואר, ובכך נכסוך הצורך לטפל בחודש, ונרשום רק את היום בחודש ינואר.) הקלט: משה נולד ב 5 (לינואר). רונית נולדה ב 7 (לינואר). דן נולד ב 5 (לינואר). רונית נולדה ב 7 משה נולד ב 5 (לינואר). פלט אפשרי א : דן נולד ב 5 (לינואר). (לינואר). רונית נולדה ב 7 דן נולד ב 5 (לינואר). פלט אפשרי ב : משה נולד ב 5 (לינואר). (לינואר). אלגוריתם מיון שמחזיר פלט אפשרי א אינו יציב, כי גם משה וגם דן נולדו ב 5 לינואר ולכן אמורים להופיע בסדרם בקלט במיון יציב. פלט אפשרי ב הוא הפלט של אלגוריתם יציב על הקלט הזו. :RADIX-SORT.8 (א) אלגוריתם זה עובד תחת ההנחה כי ממיינים מספרים (מלים) של d ספרות (אותיות) כאשר כל ספרה לוקח אחד מ k ערכים. נמספר את הספרות מקטל לגדול. (ב) האלגוריתם: נניח שהסדרה כבר מופיע במערך [n 1]A.... RADIX-SORT(A, d) 1 for i 1 to d 2 do Apply a stable sorting algorithm to sort A according to the digit i. (ג) צריך להפעיל אלגוריתם מיון יציב: שמשמר את סדר האיברים המקורי ששוי ערך במיון הנוכחי. (ד) דוגמה: 199] [839, 251, 782, 571, = A. 3 (ה) הסבר למה זה עובד: האלגוריתם מתיחס בסוף שלב i רק ל i הספרות האחרונות ולפיהם הוא ממיין נכון. (ו) הסיפור ההיסטורי על למה פתחו את האלגוריתם... מכונות שימשו למיון כרטיסים... ואלגוריתם זו איננה דורשת הרבה ערימות ביניים של כרטיסים.
(ז) ניתוח סיבוכיות כאשר משתמשים ב COUNTING-SORT למיון לפי כל ספרה..9 ערימות (heaps) ו :HEAP-SORT (א) הגדרות: ערימה הוא מארך A אם שני פרמטרים: length[a] (אורך המארך) ו heap-size[a] (מספר האיברים מהמארך שהם בערימה). מתיחסים לערימה כעץ בינארי מלא שהתאים מתואמים לצמתי העץ משמאל לימין שורה לאחר שורה. דורשים שהערך בצומת לא יהיה קטן מהערך באף צומת בתת עץ מתחתיו. PARENT(i) (ב) קוד: return i/2 LEFT(i) return 2i RIGHT(i) return 2i + 1 BUILD-HEAP(A) 1 heap-size[a] length[a] 2 for i length[a]/2 downto 1 3 do HEAPIFY(A, i) HEAPIFY(A, i) 1 l LEFT(i) 2 r RIGHT(i) 3 if (l heap-size[a] and A[l] > A[i]) 4 then largest l 5 else largest i 6 if (r heap-size[a] and A[r] > A[largest]) 7 then largest r 8 if largest i 9 then exchange A[i] A[largest] 10 HEAPIFY(A, largest) HEAPSORT(A) 1 BUILD-HEAP(A) 2 for i length[a] downto 2 3 do exchange A[1] A[i] 4 heap-size[a] heap-size[a] 1 5 HEAPIFY(A, 1) (ג) תרגיל: תהיה A ערימה עם n איברים. כתוב שיגרה שמוסיפה איבר ל A (תוך שמירה על היותה של A ערימה) בעלת זמן ריצה (n.o(log ניתן להניח שנשאר מקום בסוף המערך. HEAP-INSERT(A, x) 1 heap-size[a] heap-size[a] + 1 2 i heap-size[a] 3 while (i > 1 and A[PARENT(i)] < x) 4 do A[i] A[PARENT(i)] 5 i PARENT(i) 6 A[i] x (ד) פתרון: 4
10. תרגיל: הוכח שבמקרה הגרוע דרוש 2 2/3n השוואות למצוא את המקסימום והמינימום של n מספרים. 11. פתרון: נרשום רשימת מועמדים לכל תפקיד (מקסימום ומינימום) ונמחוק מועמדים שמועמדתם נפסלה: כאשר משווים את a i ו a j התוצאה a i < a j מוכיחה לנו ש a i אינו המקסימום וש a j אינו המינימם. עכשיו נניח שאנחנו משחקים נגד יריב שנותן לנו את התשובות להשוואות בין זוגות אך מסתיר את הערכים עצמם וגם אינו חייב לקבוע את הערגים עד סוף התהליך. במשך המשחק, היריב רושם לעצמו את התשובות שכבר נתן, כך שלא יסתור את עצמו, וגם אחרי כל תשובה מיד מחשב את היחסים שנקבעים על ידי טרנציטיביות. לפני שמשיב תשובה הוא יבדוק אם היחס כבר נקבע לפי התשובות הקודמות ואם כן יענה לפי ההכרח. אם אין תשובה הכרחית הוא נותן תשובה שמגלה לנו מינימום של מידע חדש. במקרה שטרנציטיביות קובע יחס כבר ידוע לנו שהקטן בזוג אינו מקסימום והגדול בזוג אענו מינימום ואין חידוש! לפני תחילת התהליך כל אחד מהאיברים ) i a) יכול להיות המקסימום או המינימום, כלומר שיש n מועמדים לכל תפקיד. התהליך נגמר כאשר נשאר רק איבר יחיד כמועמד למקסימום ואיבר יחיד כמועמד למינימום. לכן ההשואות חייבות להוכיח לנו ש 1 n איברים אינם יכולים להיות המקסימום וש 1 n איברים אינם יכולים להיות המינימום; סה כ עלינו לשלל 2 2n אופציות. ברור שאם נשווה את a i ו a j כאשר כבר ידוע לנו ש a i אינו המקסימום (המינימום) ולא ידוע מידע על a j היריב יענה ש (a i > a j ) a i < a j כך שלגבי a i לא קבלנו מידע חדש! (טענה דומה נכונה אם ידוע לנו מידע על a j ולא על a.) i כאשר ידוע מידע גם על a i וגם על a j היריב יענה בצורה שלא תסתר את הטרנציטיביות של התשובות הקודמות אבל שלכל היותר יפסול מועמדות אחת. לכן השוואת זוג שידוע עליהם מידע יכול לשלול לכל היותר אופציה אחת, במקרה הגרוע. אם כבר ידוע ש a i אינו המקסימום וש a j אינו המינימום ואין יחס ביניהם לפי טרנציטיביות, אז היריב יענה a i < a j ולא יגלה שום מידע שימושי חדש!!! המסקנה הוא שלא כדאי לעשות השוואה כזו!!! ניתן לעשות (לכל היותר) 2/n השוואות בין זוגות שלא ידוע עליהם מאומה ומכל השוואה כזאת להוריד גם את מספר המועמדים למקסימום וגם את מספר המועמדים למינימום באחד. נניח שעשינו k השוואות כאלו סה כ שללנו 2k אופציות. כל השוואה בין זוג שיש מידע חלקי עליהם שולל לכל היותר אופתיה אחד (במקרה הגרוע), ולכן צריכים לפחות (2n 2) 2k השוואות כאלו. סה כ נעשה 2 k k + (2n 2 2k) = 2n השוואת. נקבל מינימום עבור 2/n k = עם השוואות סה כ. 2n n/2 2 = 3n/2 2 חזרנו על ההוכחת החסם התחתון של (n Ω(n log השוואות באלגוריתם מבוסס השוואות למיון n מספרים. (כעזרה לפתור את תרגיל בית 3 שאלה 1.) העיקר הוא שעץ בינארי (עם שורש) עם!n עלים העומק שלו חייבת להיות לפחות (n.log(n!) = Ω(n log 12. בעית הבחירה problem) :(selection דיון על אלגוריתם החמישיות (ראה בספר Introduction 10.3: Selection in worst-case בפרק (Cormen, Leiserson, and Rivest של to Algorithms.linear time מומלץ מאוד להשקיע קצת זמן בהבנת האלגוריתם והניתוח שלו זאת אחת האלגוריתמים היותר מסובכים בקורס ואין זו המקום לדיון רציני בו. 5
.13 תרגיל: נתונה פרמוטציה τ של המספרים n},... 2,.{1, נאמר של τ יש חילוף ( j (i, אם i < j ו τ(j).τ(i) > תן אלגוריתם בעל סיבוכיות (n O(n log המוצא את מספר החילופים של τ. (רמז: וריאציה של אלגוריתם (.MERGE-SORT ALT-MERGE-SORT(A, p, r) 0 a 0; b 0; c 0; 1 if p < r 2 then q (p + r)/2 3 a ALT-MERGE-SORT(A, p, q) 4 b ALT-MERGE-SORT(A, q + 1, r) 5 c ALT-MERGE(A, p, q, r) 6 return (a + b + c) 14. פתרון: ALT-MERGE(A, p, q, r) 1 i p Pointer into left part 2 j q + 1 Pointer into right part 3 k p Pointer into temporary array 4 s 0 Number of swaps seen so far 5 l q (p 1) Number of elements remaining in left part 6 while (i q and j r) do 7 if (A(i) A(j)) 8 then No swap here. 9 B(k) A(i) 10 i i + 1 12 k k + 1 13 l l 1 Left side got smaller. 14 else Here there are swaps as A(i) > A(j). 15 B(k) A(j) 16 j j + 1 17 k k + 1 18 s s + l How many new swaps? 19 while (i q) do Copy rest of left side. 20 B(k) A(i) 21 i i + 1 22 k k + 1 23 while (j r) do Copy rest of right side. 24 B(k) A(j) 25 j j + 1 26 k k + 1 27 for k = p to r do Copy result back into A. 24 A(k) B(k) 25 k k + 1 26 return (s) 6